计算机操作系统第3版(汤小丹) 读书笔记

第一章 操作系统引论

操作系统的目标和作用

操作系统的目标

  1. 有效性:
    • 提高了系统资源利用率。在未配置 OS 的计算机系统中,诸如 CPU、I/O 设备等各种资源,都会因它们经常处于空闲状态而得不到充分利用;内存及外存中所存放的数据太少或者无序而浪费了大量的存储空间。配置了 OS 之后,可使 CPU 和 I/O 设备由于能保持忙碌状态而得到有效的利用,且可使内存和外存中存放的数据因有序而节省了存储空间。
    • 提高了系统的吞吐量。操作系统还可以通过合理地组织计算机的工作流程,而进一步改善资源的利用率,加速程序的运行,缩短程序的运行周期,从而提高系统的吞吐量。
  2. 方便性: 便于使用,如引入GUI操作界面。方便性、有效性是最开始的两个重要目标。
  3. 可扩展性: OS 必须具有很好的可扩充性,方能适应计算机硬件、体系结构以及应用发展的要求。这就是说,现代 OS 应采 用新的 OS 结构,如微内核结构和客户服务器模式,以便于方便地增加新的功能和模块,并 能修改老的功能和模块。
  4. 开放性: 遵循开放系统互联(OSI) 的标准,兼容软硬件,方便实现计算机互联

操作系统的作用

可以从不同的观点(角度)来观察 OS 的作用。从一般用户的观点,可把 OS 看做是用户 与计算机硬件系统之间的接口;从资源管理的观点看,则可把 OS 视为计算机系统资源的管 理者。另外,OS 实现了对计算机资源的抽象,隐藏了对硬件操作的细节,使用户能更方便 地使用机器。

  1. 用户和硬件间的接口:(1)命令方式 (2)图形界面方式(3)系统调用(在应用程序中)
  2. 管理计算机资源:如内存的分配与回收、CPU管理、I/O管理、文件管理等等
  3. 抽象计算机系统资源:隐藏计算机硬件的细节,向上提供高级抽象

推动操作系统发展的主要动力

  1. 对计算机资源利用率的追求:如能提高I/O设备和CPU利用率的SPOOLing系统,提高存储器系统利用率的虚拟存储技术,以及在网络环境下, 在服务器上配置了允许所有网络用户访问的文件系统和数据库系统。
  2. 方便用户
  3. 硬件的更新迭代
  4. 计算机体系结构的发展

操作系统的发展过程

1
2
3
4
5
6
7
8
单道批处理操作系统 => 多道程序批处理系统 
(20世纪50年代) (20世纪60年代)

=> 基于多道程序的分时系统
(不久后)

=> 微机 OS、多处理机 OS 和网 络 OS 以及分布式 OS 的形成和大发展
(20 世纪 80 年代开始至 21 世纪初)

无操作系统的计算机系统

从第一台计算机诞生(1945 年)到 20 世纪 50 年代中期的计算机,属于第一代计算机。此时的计算机是利用成千上万个真空管做成的,它的运行速度仅为每秒数千次,但体积却十 分庞大,且功耗也非常高。这时还未出现 OS。计算机操作是由用户(即程序员)采用人工操 作方式直接使用计算机硬件系统,即由程序员将事先已穿孔(对应于程序和数据)的纸带(或 卡片)装入纸带输入机(或卡片输入机),再启动它们将程序和数据输入计算机,然后启动计 算机运行。当程序运行完毕并取走计算结果之后,才让下一个用户上机。这种人工操作方式有以下两方面的缺点:(1) 用户独占全机。此时,计算机及其全部资源只能由上机用户独占。(2) CPU等待人工操作。当用户进行装带(卡)、卸带(卡)等人工操作时,CPU及内存等 资源是空闲的。

  • 问题:CPU速度提高,人工I/O速度跟不上,CPU的空闲率高
  • 解决方法:脱机输入输出技术(Off-Line I/O),事先将装有用户程序和数据的纸带(或卡片) 装入纸带输入机(或卡片机),在一台外围机的控制下,把纸带(卡片)上的数据(程序)输入到 磁带上。当 CPU 需要这些程序和数据时,再从磁带上将其高速地调入内存。当 CPU 需要输出时,可由 CPU 直接高速地把数据从内存送到磁带上,然后再 在另一台外围机的控制下,将磁带上的结果通过相应的输出设备输出。
    • 减少了主机CPU的空闲时间(外围机完成了输入输出设备和磁盘的连接)
    • 提高了I/O的速度,CPU在运行中需要数据的时候,可以从高速的磁带/磁盘中将数据调入内存

单道批处理系统

20世纪 50 年代中期发明了晶体管,人们开始用晶体管替代真空管来制作计算机,从而 出现了第二代计算机。它不仅使计算机的体积大大减小,功耗显著降低,同时可靠性也得 到大幅度提高,使计算机已具有推广应用的价值,但计算机系统仍非常昂贵。为了能充分 地利用它,应尽量让该系统连续运行,以减少空闲时间。

相比”无操作系统的计算机操作系统“多了一个监督程序(Monitor)。其自动处理过程是:首先,由监督程序将磁带上的第一个作业装入内 存,并把运行控制权交给该作业。当该作业处理完成时,又把控制权交还给监督程序,再 由监督程序把磁带(盘)上的第二个作业调入内存。

单道批处理系统的特征:

  • 自动性
  • 顺序性
  • 单道性(内存中仅有一道程序在运行)

多道批处理系统

20 世纪 60 年代中期,人们开始利用小规模集成电路来制作计算机,生产出第三代计算 机。由 IBM 公司生产的第一台小规模集成电路计算机——360 机,较之于晶体管计算机, 无论在体积、功耗、速度和可靠性上,都有了显著的改善。虽然在开发 360 机器使用的操 作系统时,为能在机器上运行多道程序而遇到了极大的困难,但最终还是成功地开发出能 在一台机器中运行多道程序的操作系统 OS/360。

  • 精髓:由调度算法从队列中选取若干作业调入内存,共享CPU等系统资源。
  • 好处:
    • 资源利用率高(CPU、内存、I/O)
    • 吞吐量大
  • 坏处:
    • 平均周转时间长(作业仍需要排队,比如就算A申请I/O中断了,CPU也会先跑B,不会跑C)
    • 无交互能力(提交后,直到其完成)
  • 要解决的问题:处理器、内存、文件、I/O、作业的管理问题

分时系统

  • 精髓:一主机,多终端共享资源,时间片
  • 要解决的问题:及时接收,及时处理(重要,影响人机交互体验)

实时系统

  • 精髓:系统能及时响应外部事件的请求,在规定的时间内完成处理。相比分时系统更强调“可靠性”,不能有差错。

微机操作系统的发展

随着 VLSI 和计算机体系结构的发展,以及应用需求的不断扩大,操作系统仍在继续发 展。由此先后形成了微机操作系统、网络操作系统等。本小节将对微机操作系统的发展作 扼要的介绍。

配置在微型机上的操作系统称为微机操作系统。最早诞生的微机操作系统是配置在 8 位微机上的 CP/M。后来出现了 16 位微机,相应地,16 位微机操作系统也就应运而生。 当微机发展为 32 位、64 位时,32 位和 64 位微机操作系统也应运而生。可见,微机操作系 统可按微机的字长来分,但也可将它按运行方式分为如下几类:

  • 单用户单任务操作系统:一次一个用户,一次一个程序,例:CP/M 和 MS-DOS
  • 单用户多任务操作系统:一次一个用户,若干程序并发执行,例:windows
  • 多用户多任务操作系统:多个用户终端连接一个主机,每个用户有若干程序。每个用户被分配时间片,在自己的时间片中,用户程序并发执行,例:UNIX

操作系统的基本特性

前面所介绍的三种基本操作系统都各自有着自己的特征,如批处理系统具有能对多个 作业进行成批处理,以获得高的系统吞吐量的特征,分时系统具有允许用户和计算机进行 人机交互特征,实时系统具有实时特征,但它们也都具有并发、共享、虚拟和异步这四个 基本特征。其中,并发特征是操作系统最重要的特征,其它三个特征都是以并发特征为前提的。

并发性

  1. 并行、并发
    • 并行:多个事件在同一时刻发生;
    • 并发(Concurrence):多个事件在同一个时间段内发生(一个时刻仍只允许发生一个事件)
    • 只有在多处理器架构上,才有并行。
  2. 进程

    • 为什么引入进程:为了并发。如果没有并发,程序是一个执行单元,要么做完,要么一点也不做,就变成单任务了
    • 进程是指在系统中能独立运行并作为资源分配的基本单位,它是由一组机器指令、数据和堆 栈等组成的,是一个能独立运行的活动实体。多个进程之间可以并发执行和交换信息。一个进程在运行时需要一定的资源,如 CPU、存储空间及 I/O 设备等。
  3. 线程

    • 进程拥有自己的资源,调度的时候有一定开销。为什么引入线程:为减少调度开销,提高并发度。
    • 一个进程有多个线程,它们共享这个进程的资源。结果:进程是分配资源的基本单位;线程是运行和调度的基本单位。

共享性

  1. 概念:系统资源供多个在内存中的并发执行的进程(线程)共享。由于各种资源的属性不同,进程对资源复用的方式也不同,目前主要实现资源共享的方式有
    如下两种。
  2. 实现方式:
    1. 互斥共享。当一个进程 A 要访 问某资源时,必须先提出请求。如果此时该资源空闲,系统便可将之分配给请求进程 A 使 用。此后若再有其它进程也要访问该资源时(只要 A 未用完),则必须等待。仅当 A 进程访 问完并释放该资源后,才允许另一进程对该资源进行访问。我们把这种资源共享方式称为 互斥式共享,而把在一段时间内只允许一个进程访问的资源称为临界资源或独占资源。计 算机系统中的大多数物理设备,以及某些软件中所用的栈、变量和表格,都属于临界资源, 它们要求被互斥地共享。
    2. 同时访问。这里所谓的“同时”,在单处理机环境下往往是宏观上的,单处理器上同时间段,不同时刻访问;多处理器上可以实现同时刻访问(真正的同时)

并发和共享是操作系统的两个最基本的特征,它们又是互为存在的条件。一方面,资源共享是以程序(进程)的并发执行为条件的,若系统不允许程序并发执行,自然不存在资源 共享问题;另一方面,若系统不能对资源共享实施有效管理,协调好诸进程对共享资源的 访问,也必然影响到程序并发执行的程度,甚至根本无法并发执行。

虚拟技术

  1. 概念:使一个物理实体对应若干个逻辑实体。物理实体(前者)是实的,即实际存在的,而后者是虚的,仅是用户感觉上的东西。在操作系统中利用了两种方式实现 虚拟技术,即时分复用技术和空分复用技术。
  2. 时分复用技术
    • 虚拟处理器技术(分时间片供多个用户使用,就好像感觉每个用户都有一个处理器为它们服务一样)
    • 虚拟设备技术(比如打印机)
  3. 空分复用技术
    • 虚拟磁盘技术(一个盘片分成几个卷,如windows上面的C、D、E盘等)
    • 虚拟存储器技术(在逻辑上扩大存储器容量,后面在将存储器一章的时候,会详细介绍)

      异步性

内存中有各种作业,处理器密集型的,I/O密集型的。由于各种原因,进程完成的时间是不可预知的,这就是进程的异步性(Asynchronism)。

操作系统的主要功能

操作系统的主要任务,是为多道程序的运行提供良好的运行环境,以保证多道程序能有条不紊地、高效地运行,并能最大程度地提高系统中各种资源的利用率和方便用户的使用。为实现上述任务,操作系统应具有这样几方面的功能:处理机管理,存储器管理,设备管理、文件管理。为了方便用户使用操作系统,还须向用户提供方便的用户接口。此外, 由于当今的网络已相当普及,已有愈来愈多的计算机接入网络中,为了方便计算机联网, 又在 OS 中增加了面向网络的服务功能。

处理机管理功能

在传统的多道程序系统中,处理机的分配和运行都是以进程为基本单位,因而对处理机的管理可归结为对进程的管理;在引入了线程的 OS 中,也包含对线程的管理。处理机管理的主要功能是创建和撤消进程(线程),对诸进程(线程)的运行进行协调,实现进程(线程) 之间的信息交换,以及按照一定的算法把处理机分配给进程(线程)。

  1. 进程控制

    • 创建,撤销,终止进程;
    • 控制进程运行中的状态转化;
    • 为进程创建,撤销,终止线程
  2. 进程同步

    进程是以异步方式运行的,并以不可预知的速度向前推进。为使多个进程能有条不紊地运行,系统中必须设置进程同步机制。进程同步的主要任务是为多个进 程(含线程)的运行进行协调。有两种协调方式:

    • 进程互斥方式,这是指诸进程(线程)在对临界资源进行访问时,应采用互斥方式。实现进程互斥的机 制是为每一个临界资源配置一把锁 W,当锁打开时,进程(线程)可以对该临界资源进行访问; 而当锁关上时,则禁止进程(线程)访问该临界资源。
    • 进程同步方式,这是指在相互合作去完成共同任务的诸进程(线程)间,由同步机构 对它们的执行次序加以协调。实现进程同步的最常用的机制则是信号量机制。
  1. 进程通信:相互合作的进程之间需要交换信息

    • 作业调度。从后备作业队列中,按算法选出若干作业,为它们分配运行所需的资源(首先是分配内存)。接着调入内存后建立进程,按算法插入就绪进程队列。
    • 进程调度。从就绪进程队列中,按算法选出一个进程,分配处理器,保存上下文信息,执行。(在多线程 OS 中,通常是把线程作为独立运行和分配处理机的基本单位,也就是从线程队列中挑选)

存储器管理功能

存储器管理的主要任务是为多道程序的运行提供良好的环境,方便用户使用存储器, 提高存储器的利用率以及能从逻辑上扩充内存。为此,存储器管理应具有内存分配、内存 保护、地址映射和内存扩充等功能。

  1. 内存分配

    • 作用:为要运行的程序分配内存空间。
    • 分类:
      • 静态内存分配:作业的内存空间在装入时已确定,不得更改;也不准作业在内存中移动
      • 动态内存分配:装入时有一个大概的基本空间,后面可以再申请;允许作业在内存中移动
    • 为了实现内存分配,在内存分配的机制中应具有这样的结构和功能:
      • 内存分配数据结构。该结构用于记录内存空间的使用情况,作为内存分配的依据;
      • 内存分配功能。系统按照一定的内存分配算法为用户程序分配内存空间;
      • 内存回收功能。系统对于用户不再需要的内存,通过用户的释放请求去完成系统的
        回收功能。
  2. 内存保护

    • 作用:确保程序都只在自己的那块内存中运行
    • 实现:一种比较简单的内存保护机制是设置两个界限寄存器,分别用于存放正在执行程序的上界和下界。系统须对每条指令所要访问的地址进行检查,如果发生越界,便发出越界中断请求,以停止该程序的执行。如果这种检查完全用软件实现,则每执行一条指令,便须增加若干条指令 去进行越界检查,这将显著降低程序的运行速度。因此,由硬件作越界检查,发现越界后与软件配合处理。
  3. 地址映射

    • 一个应用程序(源程序)经编译后,通常会形成若干个目标程序;这些目标程序再经过链 接便形成了可装入程序。这些程序的地址都是从“0”开始的,程序中的其它地址都是相对于起始地址计算的。由这些地址所形成的地址范围称为“地址空间”,其中的地址称为“逻辑地址”或“相对地址”。
    • 由内存中的一系列单元所限定的地址范围称为“内存空间”, 其中的地址称为“物理地址”。
    • 地址映射的作用:把地址空间中的逻辑地址转换为内存空间中对应的物理地址,让程序正确运行。
  4. 内存扩充

    • 作用:借助于虚拟存储技术,从逻辑上去扩充内存容量,允许内存中有更多的程序并发执行
    • 实现:
      • 请求调入功能:只装入程序的一部分和部分数据就可以让程序执行。运行到需要程序别的部分和新数据了,再叫OS从磁盘调入。
      • 置换功能:发现内存中没有足够空间来容纳需要调入的程序和数据了,叫OS看看能不能把内存中暂时不用的程序和数据调回磁盘去,腾出空间纳入亟需使用的程序和数据。

设备管理功能

设备管理用于管理计算机系统中所有的外围设备,而设备管理的主要任务是:完成用 户进程提出的 I/O 请求;为用户进程分配其所需的 I/O 设备;提高 CPU 和 I/O 设备的利用 率;提高 I/O 速度;方便用户使用 I/O 设备。为实现上述任务,设备管理应具有缓冲管理、 设备分配和设备处理以及虚拟设备等功能。

  1. 缓冲管理。如果在 I/O 设备和 CPU 之间引入缓冲,则可有效地缓和 CPU 与 I/O 设备速度不匹配的矛盾,提高 CPU 的利用率, 进而提高系统吞吐量。
  2. 设备分配。设备分配的基本任务是根据用户进程的 I/O 请求、系统的现有资源情况以及按照某种设 备的分配策略,为之分配其所需的设备。
  3. 设备处理。设备处理程序又称为设备驱动程序。其基本任务是用于实现 CPU 和设备控制器之间的 通信,即由 CPU 向设备控制器发出 I/O 命令,要求它完成指定的 I/O 操作;反之,由 CPU 接收从控制器发来的中断请求,并给予迅速的响应和相应的处理。

文件管理功能

文件管理的主要任务 是对用户文件和系统文件进行管理,以方便用户使用,并保证文件的安全性。为此,文件 管理应具有对文件存储空间的管理、目录管理、文件的读/写管理,以及文件的共享与保护 等功能。

  1. 文件存储空间的管理
  2. 目录管理
  3. 文件的读/写管理和保护

操作系统与用户之间的接口

(1)用户接口(2)程序接口(系统调用)

OS 结构设计

早期的无结构 OS(第一代)、模块化结构的 OS(第二代)和分层式结构的 OS(第三代),都统称为传统结构的 OS,而把微内核结构的 OS 称为现代结构的 OS。

传统的操作系统结构

  1. 无结构操作系统:适用于小系统,功能拓展起来,代码量一多就很难管理。
  2. 模块化操作系统:为使 OS 具有较清晰的结构,OS 不再是由众多的过程直接构成,而是将 OS 按其功能精心地划分为若干个具有一定独立性和 大小的模块。

    利用模块―接口法开发的 OS,较之无结构 OS 具有以下明显的优点:

    • 提高 OS 设计的正确性、可理解性和可维护性;
    • 增强 OS 的适应性;
    • 加速 OS 的开发过程。

      模块化结构设计仍存在下述问题:

    • 在 OS 设计时,对各模块间的接口规定很难满足在模块完成后对接口的实际需求。

    • 在 OS 设计阶段,设计者必须做出一系列的决定(决策),每一个决定必须建立在上一个决定的基础上。但在模块化结构设计中,各模块的设计齐头并进,无法寻找到一个可靠的决定顺序,造成各种决定的“无序性”,这将使程序设计人员很难做到“设计中的每一步决定都是建立在可靠的基础上”,因此模块―接口法又被称为“无序模块法”。
  3. 分层式操作系统:改进模块化操作系统,使模块之间的开发有序,但是代价是降低系统的效率。

    优点:

    • 易保证系统的正确性。自下而上的设计方式,使所有设计中的决定都是有序的,或
      者说是建立在较为可靠的基础上的,这样比较容易保证整个系统的正确性。
    • 易扩充和易维护性。在系统中增加、修改或替换一个层次中的模块或整个层次,只 要不改变相应层次间的接口,就不会影响其它层次,这必将使系统维护和扩充变得更加
      容易。

      分层结构的主要缺点是:系统效率降低了。由于层次结构是分层单向依赖的,因此必须在相邻层之间都要建立层次间的通信机制,OS 每执行一个功能,通常要自上而下地穿越多个层次,这无疑会增加系统的通信开销,从而导致系统效率的降低。

客户-服务器 模式

优点:

  • 数据分布处理:不用全放在一个主机上、
  • 灵活:改变一个客户机上的软件不会对其他的客户机和服务器造成影响

缺点:

  • 不可靠,一个服务器故障,导致多个客户机请求失败、布置格局费时--服务器负荷太重,会增加响应时间

面向对象程序设计

特点:

  • 对象(模拟现实)--易于理解
  • 继承--可扩展性
  • 封装--隐蔽性

微内核OS结构

微内核(Micro Kernel)操作系统结构,是20世纪80年代后期发展起来的。由于它能有效地支持多处理机运行,故非常适用于分布式系统环境。当前比较流行的、能支持多处理 机运行的 OS,几乎全部都采用了微内核结构,如 Carngie Mellon 大学研制的 Mach OS, 便属于微内核结构 OS;又如当前广泛使用的 Windows 2000/XP 操作系统,也采用了微内核 结构。

  1. 概念:
    为了提高操作系统的“正确性”、“灵活性”、“易维护性”和”可扩充性”,在进行现代 操作系统结构设计时,即使在单处理机环境下,大多也采用基于客户/服务器模式的微内核结构,将操作系统划分为两大部分:微内核和多个服务器。至于什么是微内核操作系统结构,现在尚无一致公认的定义,但我们可以从下面四个方面,对微内核结构的操作系统进行描述:

    • 内核足够小,它通常用于:1 实现与 硬件紧密相关的处理;2 实现一些较基本的功能;3 负责客户和服务器之间的通信。
    • 基于“客户-服务器”模式,客户指用户进程,服务器指处理这个进程的服务器,如进程服务器。微内核是来调控它们的交互的,仿佛独立于模式之外的“神之手”。

      把操作系统的绝大部 分功能都放在微内核外面的一组服务器(进程)中实现。例如用于提供对进程(线程)进行管理的进程(线程)服务器,提供虚拟存储器管理功能的虚拟存储器服务器,都是被作为进程来实现的,运行在用户态,客户与服务器之间是借助微内核提供的消息传递机制来实现信息交互的。下图为在单机环境下的 客户/服务器模式。

    • 应用“机制与策略分离”原理。机制放在微内核中,策略放在OS的其他部分。

    • 使用面向对象技术编程的
  2. 功能:

    微内核应具有哪些功能,或者说哪些功能应放在微内核内,哪些应放在微内核外,目 前尚无明确的规定。现在一般都采用“机制与策略分离”的原理,将机制部分,以及与硬 件紧密相关的部分放入微内核中。由此可知微内核通常具有如下几方面的功能:

    • 进/线程管理

      大多数的微内核 OS,对于进程管理功能的实现,都采用“机制与策略分离”的原理。 例如,为实现进程(线程)调度功能,须在进程管理中设置一个或多个进程(线程)优先级队列; 能将指定优先级进程(线程)从所在队列中取出,并将其投入执行。由于这一部分属于调度功 能的机制部分,应将它放入微内核中。应如何确定每类用户(进程)的优先级,以及应如何修 改它们的优先级等,都属于策略问题,可将它们放入微内核外的进程(线程)管理服务器中。

    • 低级存储器管理(硬件相关)

      如用于实现将用户空间的逻 辑地址变换为内存空间的物理地址的页表机制和地址变换机制,这一部分是依赖于机器的,因此放入微内核。而实现虚拟存储器管理的策略,则包含应采取何种页面置换算法,采用 何种内存分配与回收策略等,应将这部分放在微内核外的存储器管理服务器中去实现。

    • 中断和陷入管理,此时微内核的主要功能,是捕获所发生的中断和陷入事件,并进行相应的前期处理

  3. 优点:

    由于微内核 OS 结构是建立在模块化、层次化结构的基础上的,并采用了客户/服务器 模式和面向对象的程序设计技术,由此可见,微内核结构的 OS 是集各种技术优点之大成, 因而使之具有如下优点:

    • 可扩展:OS中增加一个新的服务器,就方便地拥有新功能了。
    • 可靠:有微内核的调控,客户进程或者服务器出问题了,也不会影响到别的部分
    • 可移植:微内核和硬件相关,移植的时候基本只需改动微内核,而微内核代码量小,因此可移植性高。
    • 提供了对分布式系统的支持:由于在微内核 OS 中,客户和服务器之间以及服务器和服务器之间的通信,是采用消息 传递通信机制进行的,致使微内核 OS 能很好地支持分布式系统和网络系统。
    • 融入了面向对象技术。其中的“封装”,“继承”,“对象类”和 “多态性”,以及在对象之间采用消息传递机制等,都十分有利于提高系统的“正确性”、“可 靠性”、“易修改性”、“易扩展性”等,而且还能显著地减少开发系统所付出的开销。
  4. 问题:

客户进程和服务器进程交互的时候,常常需经微内核调控,上下文切换成本高,系统运行效率受影响。

为了改善运行效率,可以重新把一些常用的操作系统基本功能,由服务器移入微内核中。这样可使客户对常用操作系统功能的请求所发生的用户/内核模式和上下文的切换的次 数,由四次或八次降为两次。但这又会使微内核的容量明显地增大,在小型接口定义和适 应性方面的优点也有所下降,同时也提高了微内核的设计代价。

第二章 进程管理

进程的基本概念

程序的顺序执行的特征:

(1)顺序性(2)封闭性(3)可再现性

程序的并发执行的特征:

(1)间断性(2)失去封闭性(3)不可再现性

进程的特征与状态

进程的特征和定义
  • 结构特征。为使程序(含数据)能独立运行,应为之配置一进程控制块,即 PCB(Process Control Block);而由程序段、相关的数据段和 PCB 三部分便构成了进程实体。在早期的 UNIX 版本中,把这三部分总称为“进程映像”。值得指出的是,在许多 情况下所说的进程,实际上是指进程实体,例如,所谓创建进程,实质上是创建进程实体 中的 PCB;而撤消进程,实质上是撤消进程的 PCB。
  • 动态性。进程的实质是进程实体的一次执行过程,因此,动态性是进程的最基本的特征。动态性还表现在:“它由创建而产生,由调度而执行,由撤消而消亡”。可见,进程实体有一定的生命期,而程序则只是一组有序指令的集合,并存放于某种介质上,其本身并不具有运动的含义,因而是静态的。
  • 并发性。这是指多个进程实体同存于内存中,且能在一段时间内同时运行。并发性是进程的重要特征,同时也成为 OS 的重要特征。引入进程的目的也正是为了使其进程实体能和其它进
    程实体并发执行;而程序(没有建立 PCB)是不能并发执行的。
  • 独立性。在传统的 OS 中,独立性是指进程实体是一个能独立运行、独立分配资源和独立接受调度的基本单位。凡未建立 PCB 的程序都不能作为一个独立的单位参与运行。
  • 异步性。这是指进程按各自独立的、 不可预知的速度向前推进,或说进程实体按异步方式运行。

现在我们再来讨论进程的定义。曾有许多人从不同的角度对进程下过定义,其中较典
型的进程定义有:

  • 进程是程序的一次执行。
  • 进程是一个程序及其数据在处理机上顺序执行时所发生的活动。
  • 进程是程序在一个数据集合上运行的过程,它是系统进行资源分配和调度的一个独
    立单位。

在引入了进程实体的概念后,我们可以把传统 OS 中的进程定义为“进程是进程实体
的运行过程,是系统进行资源分配和调度的一个独立单位”。

进程的三种基本状态
  1. 就绪状态
  2. 执行状态
  3. 阻塞状态(等待状态/封锁状态)

挂起状态

不少系统只有上面三种状态,但另一些又增加了新状态,如挂起状态、创建状态和终止状态。挂起状态有可能是终端用户在自己程序运行期间发现有可疑问题时,希望暂时使自己的程序静止下来,以便研究其执行情况或者对程序进行修改。

创建状态和终止状态
  • 创建状态:创建一个进程一般要通过两个步骤:首先,为一个新进程创建 PCB,并填写必要的管 理信息;其次,把该进程转入就绪状态并插入就绪队列之中。
  • 终止状态:进程的终止也要通过两个步骤:首先等待操作系统进行善后处理,然后将其 PCB 清零, 并将 PCB 空间返还系统。

进程控制块

为了描述和控制进程的运行,系统为每个进程定义了一个数据结构——进程控制块 PCB(Process Control Block),它是进程实体的一部分,是操作系统中最重要的记录型数据结构。PCB 是进程 存在的惟一标志。

进程控制块作用
  • PCB作用:OS 是根据 PCB 来对 并发执行的进程进行控制和管理的。例如:
    • 当 OS 要调度某进程执行时,要从该进程的 PCB 中查出其现行状态及优先级;
    • 在调度到某进程后,要根据其 PCB 中所保存的处理机状态信息,设置该进程恢复运行的现场,并根据其 PCB 中的程序和数据的内存始址,找到其程序和数据;
    • 进程在执行过程中,当需要和与之合作的进程实现同步、通信或访问文件时,也都需要访问 PCB;
    • 当进程由于某种原因而暂停执行时,又须将其断点的处理机环境保存在 PCB 中。
进程控制块中的信息

在进程控制块中,主要包括下述四方面的信息。

  1. 进程标识符
    • 内部标识符。设置内部标识符主要是为了方便系统使用。
    • 外部标识符。由用户(进程)在访问该进程时使用。为了描述进程的家族关系,还应设置父进程标识及子进程标识。此外, 还可设置用户标识,以指示拥有该进程的用户。
  2. 处理机状态。处理机状态信息主要是由处理机的各种寄存器中的内容组成的。处理机在运行时,许多信息都放在寄存器中。当处理机被中断时,所有这些信息都必须保存在 PCB 中,以便在该进程重新执行时,能从断点继续执行。
  3. 进程调度信息。在 PCB 中还存放一些与进程调度和进程对换有关的信息,包括:
    • 进程状态,指明进程的当前状态,作为进程调度和对换时的依据;
    • 进程优先级,用于描述进程使用处理机 的优先级别的一个整数,优先级高的进程应优先获得处理机;
    • 进程调度所需的其它信息, 它们与所采用的进程调度算法有关,比如,进程已等待 CPU 的时间总和、进程已执行的时 间总和等;
    • 事件,指进程由执行状态转变为阻塞状态所等待发生的事件,即阻塞原因。
  4. 进程控制信息
    • 程序和数据的地址,指进程的程序和数据所在的内存或外存地 (首)址,以便再调度到该进程执行时,能从 PCB 中找到其程序和数据;
    • 进程同步和通信机制,指实现进程同步和进程通信时必需的机制,如消息队列指针、信号量等,它们可能 全部或部分地放在 PCB 中;
    • 资源清单,即一张列出了除 CPU 以外的、进程所需的全部 资源及已经分配到该进程的资源的清单;
    • 链接指针,它给出了本进程(PCB)所在队列中 的下一个进程的 PCB 的首地址。
进程控制块的组织方式

在一个系统中,通常可拥有数十个、 数百个乃至数千个 PCB。为了能对它们加以有效 的管理,应该用适当的方式将这些 PCB 组织起来。

  • 链接方式。这是把具有同一状态的 PCB,用其中的链接字链接成一个队列.

  • 索引方式.根据所有进程的状态建立几张索引表。例如,就绪索引表、阻塞索引表等,并把各索引表在内存的首地址记录在内存的一些专用单元中。在每个索引表的表目中,记录具有相应状态的某个 PCB 在 PCB 表中的地址。

进程控制

进程控制是进程管理中最基本的功能。包括创建、终止进程,还有负责进程运行中的状态转 换。进程控制一般是由 OS 的内核中的原语来实现的。原语(Primitive)是“原子操作(Action Operation)”的过程,这个过程中的所有动作要么全做,要么全不做,在执行过程中不允许被中断。原子操作在管态下执行,常驻内存。

进程的创建

  1. 进程图(Process Graph)。子进程可以继承父进程所拥有的资源,例如,继承父进程打开的文件,继承父进程所分配到的缓冲区等。当子进程被撤消时,应将 其从父进程那里获得的资源归还给父进程。此外,在撤消父进程时,也必须同时撤消其所有的子进程。为了标识进程之间的家族关系,在 PCB 中都设置了家族关系表项,以标明自己的父进程及所有的子进程。

  2. 引起创建进程的事件。程序只有作为进程时才能在系统中运行。因此,为使程序能运行,就必须为它创建进程。导致一个进程去创建另一个进程的典型事件,可有以下四类:

    • 用户登录。在分时系统中,用户在终端键入登录命令后,如果是合法用户,系统将为该终端建立一个进程,并把它插入就绪队列中。
    • 作业调度。在批处理系统中,当作业调度程序按一定的算法调度到某作业时,便将该作业装入内存,为它分配必要的资源,并立即为它创建进程,再插入就绪队列中。
    • 提供服务。当运行中的用户程序提出某种请求后,系统将专门创建一个进程来提供 用户所需要的服务,例如,用户程序要求进行文件打印,操作系统将为它创建一个打印进 程,这样,不仅可使打印进程与该用户进程并发执行,而且还便于计算出为完成打印任务 所花费的时间。
    • 应用请求。在上述三种情况下,都是由系统内核为它创建一个新进程;而第 4 类事 件则是基于应用进程的需求,由它自己创建一个新进程,以便使新进程以并发运行方式完成特定任务。例如,某应用程序需要不断地从键盘终端输入数据,继而又要对输入数据进行相应的处理,然后,再将处理结果以表格形式在屏幕上显示。该应用进程为使这几个操作能并发执行,以加速任务的完成,可以分别建立键盘输入进程、表格输出进程。
  3. 进程的创建(Creation of Process) 用进程创建原语 Creat( )按下述步 骤创建一个新进程。

    • 申请空白 PCB。
    • 为新进程分配资源。
    • 初始化进程控制块。
    • 将新进程插入就绪队列

进程的终止

引起进程终止的事件
  1. 正常结束。调用相应指令通知 OS 进程已运行完毕。
  2. 异常结束。在进程运行期间,由于出现某些错误和故障而迫使进程终止(Termination of Process)。
    • 越界错误。这是指程序所访问的存储区已越出该进程的区域。
    • 保护错。这是指进程试图去访问一个不允许访问的资源或文件,或者以不适当的方式进行访问,例如,进程试图去写一个只读文件。
    • 非法指令。这是指程序试图去执行一条不存在的指令。出现该错误的原因,可能是程序错误地转移到数据区,把数据当成了指令。
    • 特权指令错。这是指用户进程试图去执行一条只允许 OS 执行的指令。
    • 运行超时。这是指进程的执行时间超过了指定的最大值。
    • 等待超时。这是指进程等待某事件的时间超过了规定的最大值。
    • 算术运算错。这是指进程试图去执行一个被禁止的运算,例如被 0 除。
    • I/O故障。这是指在I/O过程中发生了错误等。
  3. 外界干预。外界干预并非指在本进程运行中出现了异常事件,而是指进程应外界的请求而终止运行。这些干预有:
    • 操作员或操作系统干预。由于某种原因,例如,发生了死锁,由操作员或操作系统 终止该进程。
    • 父进程请求。由于父进程具有终止自己的任何子孙进程的权力,因而当父进程提出 请求时,系统将终止该进程。
    • 父进程终止。当父进程终止时,OS 也将它的所有子孙进程终止。
进程的终止过程
  • 根据被终止进程的标识符,从 PCB 集合中检索出该进程的 PCB,从中读出该进程
    的状态。
  • 若被终止进程正处于执行状态,应立即终止该进程的执行,并置调度标志为真,用
    于指示该进程被终止后应重新进行调度。
  • 若该进程还有子孙进程,还应将其所有子孙进程予以终止,以防它们成为不可控的
    进程。
  • 将被终止进程所拥有的全部资源,或者归还给其父进程,或者归还给系统。
  • 将被终止进程(PCB)从所在队列(或链表)中移出,等待其他程序来搜集信息。

进程的阻塞与唤醒

引起进程阻塞和唤醒的事件
  • 请求系统服务。例如,一进程请求使用某资源,如 打印机,由于系统已将打印机分配给其他进程而不能分配给请求进程,这时请求者进程只 能被阻塞,仅在其他进程在释放出打印机的同时,才将请求进程唤醒。
  • 启动某种操作。例如,进程启动了某 I/O 设备,如果只有在 I/O 设备完 成了指定的 I/O 操作任务后进程才能继续执行,则该进程在启动了 I/O 操作后,便自动进入 阻塞状态去等待。在 I/O 操作完成后,再由中断处理程序或中断进程将该进程唤醒。
  • 新数据尚未到达。例如,有两个进程, 进程 A 用于输入数据,进程 B 对输入数据进行加工。假如 A 尚未将数据输入完毕,则进程 B 将因没有所需的处理数据而阻塞;一旦进程 A 把数据输入完毕,便可去唤醒进程 B。
  • 无新工作可做。例如,系统中的发送进程,其主要工作是发送数据,若已有 的数据已全部发送完成而又无新的发送请求,这时(发送)进程将使自己进入阻塞状态; 仅当又有进程提出新的发送请求时,才将发送进程唤醒。
进程阻塞过程
  • 调用阻 塞原语 block 把自己阻塞
  • 进入 block 过程 后,由于此时该进程还处于执行状态,所以应先立即停止执行,把进程控制块中的现行状 态由“执行”改为“阻塞”,并将 PCB 插入阻塞队列。
  • 最后,转调度程序 进行重新调度,将处理机分配给另一就绪进程并进行切换,亦即,保留被阻塞进程的处理 机状态(在 PCB 中),再按新进程的 PCB 中的处理机状态设置 CPU 的环境。
进程唤醒过程
  • 调用唤醒原语 wakeup( ),将等待某事件的进程唤
  • 唤醒原语执行的过程是:首先把被阻塞的进程从等待该事件的阻塞队列中移出,将其 PCB 中的现行状态由阻塞改为就绪,然后再将该 PCB 插入到就绪队列中。

block 原语和 wakeup 原语是一对作用刚好相反的原语。因此,如果在某进 程中调用了阻塞原语,则必须在与之相合作的另一进程中或其他相关的进程中安排唤醒原 语,以能唤醒阻塞进程;否则,被阻塞进程将会因不能被唤醒而长久地处于阻塞状态,从 而再无机会继续运行。

进程的挂起与激活

进程的挂起

用户进程请求将自己挂起,或父进程请求将 自己的某个子进程挂起,系统将利用挂起原语suspend( )将指定进程或处于阻塞状态的进程挂起。

  • 首先检查被挂起进程的状态,若处于活动就绪状态,便将 其改为静止就绪; 对于活动阻塞状态的进程,则将之改为静止阻塞
  • 为了方便用户或父进 程考查该进程的运行情况而把该进程的 PCB 复制到某指定的内存区域
  • 若被挂起的 进程正在执行,则转向调度程序重新调度。
进程的激活过程

系统将利用激活原语 active( )将指定进程激活。

  • 激活原语先将进程从外存调入内 存,检查该进程的现行状态,
  • 若是静止就绪,便将之改为活动就绪;若为静止阻塞,便将 之改为活动阻塞。
  • 假如采用的是抢占调度策略,则每当有新进程进入就绪队列时,应检查是否要进行重新调度,即由调度程序将被激活进程与当前进程进行优先级的比较,如果被激活进程的优先级更低,就不必重新调度;否则,立即剥夺当前进程的运行,把处理机分 配给刚被激活的进程。

进程同步

由于进程的异步性,也会给系统造成混乱,尤其是在他们争用临界资源时。例如,当多个进程去争用一台打印 机时,有可能使多个进程的输出结果交织在一起,难于区分;而当多个进程去争用共享变 量、表格、链表时,有可能致使数据处理出错。进程同步的主要任务是对多个相关进程在 执行次序上进行协调,以使并发执行的诸进程之间能有效地共享资源和相互合作。

进程同步的基本概念

两种形式的制约关系
  1. 间接相互制约关系。同处于一个系统中的进程,通常都共享着某种系统资源,如共 享 CPU、共享 I/O 设备等。
  2. 直接相互制约关系。这种制约主要源于进程间的合作。
临界资源

许多硬件资源如打印机、磁带机等,都属于临界资源 (Critical Resouce),诸进程间应采取互斥方式,实现对这种资源的共享。例如生产者和消费者问题

临界区
  • 每个进程中访问临界资源的那段代码称为临界区(critical section)。显然, 若能保证诸进程互斥地进入自己的临界区,便可实现诸进程对临界资源的互斥访问。
  • 在临界区前面增加一段用于检查临界资源的代码,把这段代码称为进入区(entry section)
  • 在临界区后面也要加上一段称为退出区(exit section)的代码,用于将临界区正被访问的 标志恢复为未被访问的标志。
同步机制应遵循的规则

为实现进程互斥地进入自已的临界区,可用软件方法,更多的是在系统中设置专门的同步机构来协调各进程间的运行。所有同步机制都应遵循下述四条准则:

  • 空闲让进。当无进程处于临界区时,表明临界资源处于空闲状态,应允许一个请求进入临界区的进程立即进入自己的临界区,以有效地利用临界资源。
  • 忙则等待。当已有进程进入临界区时,表明临界资源正在被访问,因而其它试图进入临界区的进程必须等待,以保证对临界资源的互斥访问。
  • 有限等待。对要求访问临界资源的进程,应保证在有限时间内能进入自己的临界区,以免陷入“死等”状态。
  • 让权等待。当进程不能进入自己的临界区时,应立即释放处理机,以免进程陷入“忙等”状态。

信号量机制

整型信号量

整型信号量定义为一个用于表示资源数目的整型量 S,它与一般整型量不同,除初始化外,仅能通过两个标准的原子操作(Atomic Operation) wait(S)和signal(S) 来访问。这两个操作一直被分别称为 P、V 操作。Wait(S)和 signal(S)操作可 描述为:

1
2
3
4
5
6
7
8
9
10
11
wait(S):  	while S<=0 do no-op;
S:=S-1;
signal(S): S:=S+1;

```

只要是信号量 S≤0,就会不断地测试。因此,该机制并未遵循“让权等待”的准则,而是使进程处于“忙等”的状态。

##### 记录型信号量

记录型信号量机制则 是一种不存在“忙等”现象的进程同步机制。但在采取了“让权等待”的策略后,又会出现多个进程等待访问同一临界资源的情况。为此,在信号量机制中,除了需要一个用于代表资源数目的整型变量 value 外,还应增加一个进程链表指针 L,用于链接上述的所有等待进程。记录型信号量是由于它采用了记录型的数据结构而得名的。它所包含的上述两个数 据项可描述为:

type semaphore=record
value: integer;
L: list of process;
end

1
2

相应地,wait(S)和 signal(S)操作可描述为:

procedure wait(S)
var S:semaphore;
begin
S.value:=S.value-1;
if S.value<0 then block(S.L);
end
procedure signal(S)
var S: semaphore; begin
S.value:=S.value+1;
if S.value<=0 then wakeup(S.L);
end

1
2
3
4
5
6

- 当 S.value<0 时,表示该类资源已 分配完毕,因此进程应调用 block 原语,进行自我阻塞,放弃处理机,并插入到信号量链表 S.L 中。
- 若 加 1 后仍是 S.value≤0,则表示在该信号量链表中,仍有等待该资源的进程被阻塞,故还应 调用 wakeup 原语,将 S.L 链表中的第一个等待进程唤醒。

##### AND 型信号量
在有些应用场 合,是一个进程需要先获得两个或更多的共享资源后方能执行其任务。假定现有两个进程 A 和 B,他们都要求访问共享数据 D 和 E。为此,可为 这两个数据分别设置用于互斥的信号量 Dmutex 和 Emutex,并令它们的初值都是 1。

process A: wait(Dmutex); 于是 Dmutex=0
process B: wait(Emutex); 于是 Emutex=0
process A: wait(Emutex); 于是 Emutex=-1 A 阻塞
process B: wait(Dmutex); 于是 Dmutex=-1 B 阻塞
`

此时的进程 A 和 B 已进入死锁状态。AND 同步机制的基本思想是:将进程在整个运行过程中需要的所有资源,一次性全部地分配给进程,待进程使用完后再一起释放。对若干个临界资源的分配,采取原子操作方式:要么把它所请求的资源全部分配到进程,要么一个也不分配。

信号量集
  • 一次需要N个某类临界资源时,就要进行N次wait操作--低效又可能死锁
  • 一般信号量集用于同时需要多种资源、每种占用的数目不同、且可分配的资源还存在一个临界值时的处理;
  • 基本思想:进程对信号量Si的测试值为ti(用于信号量的判断,即Si < ti,表示资源数量低于ti时,便不予分配),占用值为di(用于信号量的增减,即Si = Si - di和Si = Si + di)
  • Swait(S1, t1, d1; …; Sn, tn, dn);
  • Ssignal(S1, d1; …; Sn, dn);
信号量的应用
  • 利用信号量实现进程互斥。将各进程访问临界资源的临界区 CS 置于 wait(mutex)和 signal(mutex)操作 之间即可。
  • 利用信号量实现前趋关系

管程机制

每个要访问临界资源的进程都必须自备同步操作 wait(S)和 signal(S)。这就使大量的同步操作分散在各个进程中。

  • 系统的管理带来了麻烦
  • 同步操作的使用不当而导致系统死锁。

在解决上述问题的过程中,便产生了一种新的进程同步工具——管程(Monitors)。

进程通信

  • 低级通信:进程之间的互斥和同步,由于其所交换的信息量少而被归结为低级通信。在进程互斥中,进程通过只修改信号量来向其他进程表明临界资源是否可用。
  • 高级通信:指用户可直接利用操作系统所提供的一组通信命令高效地传送大量数据的一种通信方式。操作系统隐藏了进程通信的实现细节。这样就大大减少了通信程序编制上的复杂性。

进程通信的类型

共享存储器系统
  • 基于共享数据结构的通信方式。这里,公用数据结构的设置及对进程间同步的处理,都是程序员的职 责。这无疑增加了程序员的负担,而操作系统却只须提供共享存储器。因此,这种通信方式是低效的,只适于传递相对少量的数据。
  • 基于共享存储区的通信方式。为了传输大量数据,在存储器中划出了一块共享存储区,诸进程可通过对共享存储区中数据的读或写来实现通信。这种通信方式属于高级通信。
消息传递系统

消息传递系统(Message passing system)是当前应用最为广泛的一种进程间的通信机制。 在该机制中,进程间的数据交换是以格式化的消息(message)为单位的。在当今最为流行的微内核操作系统中,微内核与服务器之间的通 信,无一例外地都采用了消息传递机制。又因其实现方式的不同而进一步分成直接通信方式和间接通信方式两种。

管道通信系统

所谓“管道”,是指用于连接一个读进程和一个写进程以实现它们之间通信的一个共享 文件,又名 pipe 文件。为了协调双方的通信,管道机制必须提供以下三方面的协调能力:

  • 互斥,即当一个进程正在对 pipe 执行读/写操作时,其它(另一)进程必须等待。
  • 同步,指当写(输入)进程把一定数量(如 4 KB)的数据写入 pipe,便去睡眠等待,直
    到读(输出)进程取走数据后,再把它唤醒。当读进程读一空 pipe 时,也应睡眠等待,直至写 进程将数据写入管道后,才将之唤醒。
  • 确定对方是否存在,只有确定了对方已存在时,才能进行通信。

消息传递通信的实现方法

直接通信方式

这是指发送进程利用 OS 所提供的发送命令,直接把消息发送给目标进程。此时,要求 发送进程和接收进程都以显式方式提供对方的标识符。

间接通信方式

间接通信方式指进程之间的通信需要通过作为共享数据结构的实体。该实体用来暂存 发送进程发送给目标进程的消息;接收进程则从该实体中取出对方发送给自己的消息。通 常把这种中间实体称为信箱。系统为信箱通信提供了若干条原语,分别用于信箱的创建、撤消和消息的发送、接收等。

消息传递通信的实现方法

直接通信方式
间接通信方式

消息传递系统实现中的若干问题

消息缓冲队列通信机制

线程

线程的基本概念

引入线程

进程的目的,是为了使多个程序能并发执行,以提高资源利用率和系统吞吐量,那么,在操作系统中再引入线程,则是为了减少程序在并发执行时所付出的时空开销,使 OS 具有更好的并发性。

换言之,由于进程是一个资源的拥有者,因而在创建、撤消和切换中,系统必须为之付出较大的时空开销。正因如此,在系统中所设置的进程,其数目不宜过多,进程切换的 频率也不宜过高,这也就限制了并发程度的进一步提高。

因为进程“太重”,致使实现多处理机环境下的进程调度、分派和切换时,都需花费较大的时间和空间开销。如果在 OS 中引入线程,以线程作为调度和分派的基本单位, 则可以有效地改善多处理机系统的性能。

线程与进程的比较
  1. 调度。

    线程作为调度和分派的基本单位,而进程作为资源 拥有的基本单位,把传统进程的两个属性分开,使线程基本上不拥有资源,这样线程便能 轻装前进,从而可显著地提高系统的并发程度。在同一进程中,线程的切换不会引起进程 的切换,但从一个进程中的线程切换到另一个进程中的线程时,将会引起进程的切换。

  2. 并发性

    进程之间可以并发执行,而且在一个进程中的多个线 程之间亦可并发执行,使得操作系统具有更好的并发性,从而能更加有效地提高系统资源 的利用率和系统的吞吐量。

  3. 拥有资源

    进程都可以拥有资源,是系统 中拥有资源的一个基本单位。一般而言,线程自己不拥有系统资源(也有一点必不可少的资 源),但它可以访问其隶属进程的资源,即一个进程的代码段、数据段及所拥有的系统资源, 如已打开的文件、I/O 设备等,可以供该进程中的所有线程所共享。

  4. 系统开销

    在创建或撤消进程时,系统都要为之创建和回收进程控制块,分配或回收资源,如内 存空间和 I/O 设备等,操作系统所付出的开销明显大于线程创建或撤消时的开销。类似地, 在进程切换时,涉及到当前进程 CPU 环境的保存及新被调度运行进程的 CPU 环境的设置, 而线程的切换则仅需保存和设置少量寄存器内容,不涉及存储器管理方面的操作,所以就 切换代价而言,进程也是远高于线程的。

线程的属性
  • 轻型实体。

    线程中的实体基本上不拥有系统资源,只是有一点必不可少的、 能保证其独立运行的资源,比如,在每个线程中都应具有一个用于控制线程运行的线程控制块 TCB,用于指示被执行指令序列的程序计数器,保留局部变量、少数状态参数和返回地址等的一组寄存器和堆栈。

  • 独立调度和分派的基本单位。

    在多线程 OS 中,线程是能独立运行的基本单位,因 而也是独立调度和分派的基本单位。由

  • 可并发执行。

    在一个进程中的多个线程之间可以并发执行,甚至允许在一个进程中 的所有线程都能并发执行;同样,不同进程中的线程也能并发执行。

  • 共享进程资源。

    在同一进程中的各个线程都可以共享该进程所拥有的资源,这首先 表现在所有线程都具有相同的地址空间(进程的地址空间)。这意味着线程可以访问该地址空 间中的每一个虚地址;此外,还可以访问进程所拥有的已打开文件、定时器、信号量机构等。

线程的状态
  1. 状态参数
    • 寄存器状态,它包括程序计数器 PC 和堆栈指针中的内容;
    • 堆栈,在堆栈中通常保存有局部变量和返回地址;
    • 线程运行状态,用于描述线程正处于何种运行状态;
    • 优先级,描述线程执行的优先程度;
    • 线程专有存储器,用于保存线程自己的局部变量拷贝;
    • 信号屏蔽,即对某些信号加以屏蔽。
  2. 线程运行状态。
    • 执行状态,表示线程正获得处理机而运行;
    • 就绪状态,指线程已具备了各种执行条件,一旦获得 CPU 便可执行的状态;
    • 阻塞状态,指线程在执行中因某事件而受阻,处于暂停执行时的状态。

线程间的同步和通信

在多线程 OS 中通常提供多种同步机制,如互斥锁、条件变量、计数信号量以及多读、单写锁等。

线程的实现方式

线程已在许多系统中实现,但各系统的实现方式并不完全相同。在有的系统中,特别 是一些数据库管理系统如 Infomix,所实现的是用户级线程(UserLevel Threads);而另一些系 统(如 Macintosh 和 OS/2 操作系统)所实现的是内核支持线程(KernelSupported Threads); 还 有一些系统如 Solaris 操作系统,则同时实现了这两种类型的线程。

内核支持线程

内核支持线程 KST(Kernel Supported Threads)无论是用户进程中的线程,还是系统进程中的线程,他们的创建、撤消和切换等也是依靠内核,在内核空间实现的。此外,在内核空间还为每一个内核支持线程设置了一个线程控制块,内核是根据该控制块而感知某线程的存在,并对其加以控制。

优点:

  • 在多处理器系统中,内核能够同时调度同一进程中多个线程并行执行;
  • 如果进程中的一个线程被阻塞了,内核可以调度该进程中的其它线程占有处理器运
    行,也可以运行其它进程中的线程;
  • 内核支持线程具有很小的数据结构和堆栈,线程的切换比较快,切换开销小;
  • 内核本身也可以采用多线程技术,可以提高系统的执行速度和效率。 内核支持线程

缺点是:对于用户的线程切换而言,其模式切换的开销较大,在同一个进程中,从一个线程切换到另一个线程时,需要从用户态转到内核态进行,这是因为用户进程的线程在用户态运行,而线程调度和管理是在内核实现的,系统开销较大。

用户级线程

用户级线程 ULT(User Level Threads)仅存在于用户空间中。对于这种线程的创建、撤 消、线程之间的同步与通信等功能,都无须利用系统调用来实现。对于用户级线程的切换, 通常发生在一个应用进程的诸多线程之间,这时,也同样无须内核的支持。

优点:

  • 线程切换不需要转换到内核空间,从而节省了模式切换的开销,也节省了内核的宝贵资源。
  • 调度算法可以是进程专用的。在不干扰操作系统调度的情况下,不同的进程可以根据自身需要,选择不同的调度算法对自己的线程进行管理和调度,而与操作系统的低级调度算法是无关的。
  • 用户级线程的实现与操作系统平台无关,因此,用户级线程甚至可以在不支持线程机制的操作系统平台上实现。

缺点:

  • 系统调用的阻塞问题。在基于进程机制的操作系统中,大多数系统调用将阻塞进程, 因此,当线程执行一个系统调用时,不仅该线程被阻塞,而且进程内的所有线程都会被阻塞。而在内核支持线程方式中,则进程中的其它线程仍然可以运行。
  • 在单纯的用户级线程实现方式中,多线程应用不能利用多处理机进行多重处理的优点。内核每次分配给一个进程的仅有一个 CPU,因此进程中仅有一个线程能执行,在该线 程放弃 CPU 之前,其它线程只能等待。

第三章 处理机调度与死锁